package se.gala.users;

import se.gala.money.Currencies;
import se.gala.money.MoneyInt;
import se.gala.wallet.DifferentCurrencyException;
import se.gala.wallet.InsufficientFundsException;

public class PlayerBalance extends PlayerBalanceObservable {
	
	private Currencies realCashCurrency;
	private MoneyInt realCashBalance;
	
	public PlayerBalance(Currencies realCashCurrency) {
		this.realCashCurrency = realCashCurrency;
		this.realCashBalance = new MoneyInt("0", realCashCurrency, false);
	}
	
	public synchronized void setRealCashBalance(MoneyInt newAmount) {
		this.realCashBalance = newAmount;
		setChanged();
		notifyObservers(newAmount);
	}
	
	public Currencies getRealCashCurrency() {
		return realCashCurrency;
	}
	
	public MoneyInt getRealCashBalance() {
		return realCashBalance;
	}
	
	public MoneyInt moneyIntFactory(Number n) {
		return MoneyInt.moneyIntFactory(n, realCashCurrency);
	}
	
	public static void appendAmount(MoneyInt balance, MoneyInt amount) throws DifferentCurrencyException, InsufficientFundsException {
		if (!balance.equals(amount.getCurrency())) {
			throw new DifferentCurrencyException();
		}
		appendAmount(balance, amount.getCentValueAsInt(), false);
	}
	
	public static void appendAmount(MoneyInt balance, int centValue, boolean allowsNegative) throws InsufficientFundsException {
		int oldCentValue = balance.getCentValueAsInt();
		final int newIntValue = oldCentValue + centValue;
		if (!allowsNegative && newIntValue < 0) {
			throw new InsufficientFundsException("Required: [" + centValue + "], available: [" + oldCentValue + "]");
		}
		balance.setNegative(newIntValue < 0);
		balance.parseCentValueString("" + Math.abs(newIntValue));
	}

	protected synchronized void updateRealCashBalance(MoneyInt difference) throws InsufficientFundsException {
		appendAmount(realCashBalance,
				difference.getCentValueAsInt(), false);
		setChanged();
		notifyObservers(difference);
//		log("[" + difference + "] " + realCashBalance);
	}
	
}
